#include "imageprocessor.h"
#include <QDebug>
ImageProcessor::ImageProcessor(QObject *parent) : QObject(parent)
    , m_dpiConfig(150.0, 150.0)  // Martin Fowler重构：默认配置，可通过依赖注入覆盖
{
}
// Martin Fowler重构：Introduce Parameter - DPI依赖注入实现
void ImageProcessor::setDpiConfiguration(const DpiConfiguration& config)
{
    DpiConfiguration oldConfig = m_dpiConfig;
    m_dpiConfig = config;
    if (oldConfig.processingDpi != config.processingDpi) {
        // Martin Fowler重构：添加A4尺寸变化的详细日志
        QSize oldA4 = DpiConfiguration(oldConfig.processingDpi, oldConfig.processingDpi).calculateA4Size();
        QSize newA4 = config.calculateA4Size();
    }
    if (oldConfig.displayDpi != config.displayDpi) {
    }
}
QColor ImageProcessor::detectBackgroundColor(const QImage& image)
{
    // 使用角落和邊緣的像素來檢測背景色
    QList<QColor> samples;
    samples << QColor(image.pixel(0, 0))
            << QColor(image.pixel(image.width()-1, 0))
            << QColor(image.pixel(0, image.height()-1))
            << QColor(image.pixel(image.width()-1, image.height()-1));
    
    // 計算平均顏色
    int r = 0, g = 0, b = 0;
    for (const QColor& color : samples) {
        r += color.red();
        g += color.green();
        b += color.blue();
    }
    return QColor(r/samples.size(), g/samples.size(), b/samples.size());
}
bool ImageProcessor::isEmptyRow(const QImage& image, int y, const QColor& bgColor, int tolerance)
{
    int emptyPixels = 0;
    for (int x = 0; x < image.width(); x += 4) {  // 每4個像素採樣一次以提高性能
        QColor pixelColor(image.pixel(x, y));
        if (qAbs(pixelColor.red() - bgColor.red()) <= tolerance &&
            qAbs(pixelColor.green() - bgColor.green()) <= tolerance &&
            qAbs(pixelColor.blue() - bgColor.blue()) <= tolerance) {
            emptyPixels++;
        }
    }
    // 如果超過95%的採樣像素是背景色，認為是空行
    return (emptyPixels * 400 / image.width()) > 95;
}
int ImageProcessor::findBestSplitPosition(const QImage& image, int startY, 
                                        int targetHeight, const QColor& bgColor)
{
    // 首先在目標高度之前搜索（優先選擇較短的切片）
    int searchStart = qMax(startY + targetHeight - 100, startY);  // 向上搜索100像素
    int searchEnd = startY + targetHeight;  // 目標高度
    int bestPosition = startY + targetHeight;  // 默認位置
    int maxEmptyRows = 0;
    int currentEmptyRows = 0;
    // 添加调试信息
    static int callCount = 0;
    callCount++;
    if (callCount % 100 == 0) {
    }
    // 首先在目標高度之前搜索
    for (int y = searchStart; y < searchEnd; ++y) {
        if (isEmptyRow(image, y, bgColor)) {
            currentEmptyRows++;
            if (currentEmptyRows > maxEmptyRows) {
                maxEmptyRows = currentEmptyRows;
                bestPosition = y - currentEmptyRows / 2;  // 取空白區域的中間
            }
        } else {
            currentEmptyRows = 0;
        }
    }
    // 如果在目標高度之前沒有找到合適的分割點，才考慮向後搜索
    if (maxEmptyRows == 0 && searchEnd < image.height()) {
        int extendedSearchEnd = qMin(searchEnd + 50, image.height());  // 最多向後搜索50像素
        currentEmptyRows = 0;
        for (int y = searchEnd; y < extendedSearchEnd; ++y) {
            if (isEmptyRow(image, y, bgColor)) {
                currentEmptyRows++;
                if (currentEmptyRows > maxEmptyRows) {
                    maxEmptyRows = currentEmptyRows;
                    bestPosition = y - currentEmptyRows / 2;
                }
            } else {
                currentEmptyRows = 0;
            }
        }
    }
    // 如果完全沒找到空行，就使用目標高度
    if (maxEmptyRows == 0) {
        bestPosition = qMin(startY + targetHeight, image.height());
    }
    // 防止无限循环的额外检查
    if (bestPosition <= startY) {
        bestPosition = startY + targetHeight;  // 强制前进目标高度
    }
    // 确保不会超出图片边界
    if (bestPosition >= image.height()) {
        bestPosition = image.height();
    }
    return bestPosition;
}
QImage ImageProcessor::createPaddedSlice(const QImage& source, int targetHeight, 
                                       const QColor& bgColor)
{
    QImage result(source.width(), targetHeight, QImage::Format_RGB32);
    result.fill(bgColor);
    // 將源圖像繪製到結果圖像上
    QPainter painter(&result);
    painter.drawImage(0, 0, source);
    return result;
}
int ImageProcessor::calculateImagePageCount(const QImage &image, ColumnMode mode)
{
    if (image.isNull())
        return 0;
    // 只按A4大小切割，不考虑mode
    QList<int> splitPositions = calculateSplitPositions(image);
    int sliceCount = splitPositions.size();
    // 对于不同的mode，页数计算方式：
    // SingleColumn: 每个切片一页
    // TwoColumns: 每2个切片一页  
    // ThreeColumns: 每3个切片一页
    int pagesPerSlice = static_cast<int>(mode);
    int pageCount = (sliceCount + pagesPerSlice - 1) / pagesPerSlice;
    return pageCount;
}
QList<int> ImageProcessor::calculateSplitPositions(const QImage &image)
{
    QList<int> splitPositions;
    if (image.isNull()) {
        return splitPositions;
    }
    // 檢測背景色
    QColor bgColor = detectBackgroundColor(image);
    // A4紙的寬高比 - 固定按A4大小切割
    const double A4_RATIO = 297.0 / 210.0;
    // 計算A4切割高度（固定高度）
    int a4Height = static_cast<int>(image.width() * A4_RATIO);
    // 預計算所有分割位置
    int y = 0;
    int splitCount = 0;
    while (y < image.height()) {
        // 尋找最佳分割位置
        int splitPos = findBestSplitPosition(image, y, a4Height, bgColor);
        splitPositions.append(splitPos);
        splitCount++;
        // 防止无限循环
        if (splitPos <= y) {
            break;
        }
        y = splitPos;
        // 防止计算过多分割点（调试用）
        if (splitCount > 100) {
            break;
        }
    }
    return splitPositions;
}
QList<QImage> ImageProcessor::generateSlicesAtPositions(const QImage &image, 
                                                        const QList<int> &splitPositions, 
                                                        int startSliceIndex, int sliceCount)
{
    QList<QImage> slices;
    if (image.isNull() || splitPositions.isEmpty() || sliceCount <= 0)
        return slices;
    // 檢測背景色
    QColor bgColor = detectBackgroundColor(image);
    // A4紙的寬高比 - 固定按A4大小切割
    const double A4_RATIO = 297.0 / 210.0;
    // 計算A4切割高度（固定高度）
    int a4Height = static_cast<int>(image.width() * A4_RATIO);
    // 根據預計算的位置生成切片
    int endSliceIndex = qMin(startSliceIndex + sliceCount, splitPositions.size());
    for (int i = startSliceIndex; i < endSliceIndex; ++i) {
        int startY = (i == 0) ? 0 : splitPositions[i - 1];
        int endY = splitPositions[i];
        if (startY < image.height() && endY <= image.height()) {
            QImage slice = image.copy(0, startY, image.width(), endY - startY);
            slices.append(createPaddedSlice(slice, a4Height, bgColor));
        }
    }
    return slices;
}
QList<QImage> ImageProcessor::splitImage(const QImage &image, ColumnMode mode)
{
    QList<QImage> pages;
    if (image.isNull()) {
        return pages;
    }
    // 檢測背景色
    QColor bgColor = detectBackgroundColor(image);
    // A4紙的寬高比
    const double A4_RATIO = 297.0 / 210.0;
    // 計算基本切割高度（單列時的高度）
    int baseHeight = static_cast<int>(image.width() * A4_RATIO);
    // 根據列數調整切割高度
    int pageHeight = baseHeight * static_cast<int>(mode);
    // 切割圖片
    int y = 0;
    QList<QImage> slices;
    while (y < image.height()) {
        // 尋找最佳分割位置
        int splitPos = findBestSplitPosition(image, y, pageHeight, bgColor);
        // 切割並填充到目標高度
        QImage slice = image.copy(0, y, image.width(), splitPos - y);
        slices.append(createPaddedSlice(slice, pageHeight, bgColor));
        y = splitPos;
    }
    // 將切片按列數排列到A4頁面上
    int columns = static_cast<int>(mode);
    for (int i = 0; i < slices.size(); i += columns) {
        QList<QImage> pageSlices;
        for (int j = 0; j < columns && (i + j) < slices.size(); ++j) {
            pageSlices.append(slices[i + j]);
        }
        pages.append(arrangeColumnsOnA4(pageSlices));
    }
    return pages;
}
QImage ImageProcessor::arrangeColumnsOnA4(const QList<QImage>& columns)
{
    // Martin Fowler重构：Replace Magic Number - 使用动态DPI计算A4尺寸
    QSize a4Size = getCurrentA4Size();
    const int A4_WIDTH = a4Size.width();
    const int A4_HEIGHT = a4Size.height();
    // 創建A4畫布
    QImage result(A4_WIDTH, A4_HEIGHT, QImage::Format_RGB32);
    result.fill(Qt::white);
    QPainter painter(&result);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setRenderHint(QPainter::SmoothPixmapTransform);
    // 計算列間距和邊距（按比例調整）
    int margin = 60;   // 30 * 2 (150DPI/72DPI)
    int columnSpacing = 40;  // 20 * 2
    // 計算可用區域
    int availableWidth = A4_WIDTH - (2 * margin);
    int availableHeight = A4_HEIGHT - (2 * margin);
    // 根據mode計算應該的列數（即使實際切片數量不足）
    int totalColumns = (columns.first().width() * 2 > columns.first().height()) ? 1 : 
                      (columns.first().height() > columns.first().width() * 3) ? 3 : 2;
    // 計算單列寬度（考慮間距）
    int columnWidth = (availableWidth - (columnSpacing * (totalColumns - 1))) / totalColumns;
    // 找出最高的切片來計算縮放比例
    double maxHeightRatio = 0;
    for (const QImage& column : columns) {
        double ratio = static_cast<double>(column.height()) * columnWidth / 
                      (column.width() * availableHeight);
        maxHeightRatio = qMax(maxHeightRatio, ratio);
    }
    // 如果需要，調整縮放以適應高度
    if (maxHeightRatio > 1.0) {
        columnWidth = static_cast<int>(columnWidth / maxHeightRatio);
    }
    // 計算起始x坐標，使列居中
    int totalWidth = columnWidth * totalColumns + columnSpacing * (totalColumns - 1);
    int startX = margin + (availableWidth - totalWidth) / 2;
    // 繪製每一列
    int x = startX;
    for (int i = 0; i < totalColumns; ++i) {
        if (i < columns.size()) {
            // 使用高質量縮放
            QImage scaledColumn = columns[i].scaled(QSize(columnWidth, availableHeight),
                                                  Qt::KeepAspectRatio,
                                                  Qt::SmoothTransformation);
            // 計算y坐標使圖像垂直居中
            int y = (A4_HEIGHT - scaledColumn.height()) / 2;
            // 繪製圖像
            painter.drawImage(x, y, scaledColumn);
        }
        // 更新x坐標（無論是否繪製了圖像）
        x += columnWidth + columnSpacing;
    }
    return result;
}
int ImageProcessor::calculatePageHeight(const QImage &image, ColumnMode mode)
{
    // A4紙的寬高比
    const double A4_RATIO = 210.0 / 297.0;
    // 計算基本高度（單列時的高度）
    int baseHeight = static_cast<int>(image.width() * A4_RATIO);
    // 根據列數返回實際高度
    return baseHeight * static_cast<int>(mode);
}
QImage ImageProcessor::enhanceImage(const QImage& image, const EnhanceParams& params)
{
    QImage result = image;
    // 按顺序应用各种处理
    if (params.autoRotate) {
        result = autoRotateImage(result);
    }
    if (params.brightness != 0) {
        result = adjustBrightness(result, params.brightness);
    }
    if (params.contrast != 0) {
        result = adjustContrast(result, params.contrast);
    }
    if (params.sharpness > 0) {
        result = sharpenImage(result, params.sharpness);
    }
    if (params.denoise) {
        result = denoiseImage(result);
    }
    if (params.colorMode != 0) {
        result = adjustColorMode(result, params.colorMode);
    }
    return result;
}
QImage ImageProcessor::adjustBrightness(const QImage& image, int value)
{
    QImage result = image;
    // 将 -100 到 100 的值映射到实际的亮度调整范围
    int adjustment = value * 255 / 100;
    for (int y = 0; y < result.height(); ++y) {
        for (int x = 0; x < result.width(); ++x) {
            QColor color(result.pixel(x, y));
            int r = qBound(0, color.red() + adjustment, 255);
            int g = qBound(0, color.green() + adjustment, 255);
            int b = qBound(0, color.blue() + adjustment, 255);
            result.setPixel(x, y, qRgb(r, g, b));
        }
    }
    return result;
}
QImage ImageProcessor::adjustContrast(const QImage& image, int value)
{
    QImage result = image;
    // 将 -100 到 100 的值映射到对比度因子
    double factor = 1.0 + value / 100.0;
    for (int y = 0; y < result.height(); ++y) {
        for (int x = 0; x < result.width(); ++x) {
            QColor color(result.pixel(x, y));
            int r = qBound(0, int((color.red() - 128) * factor + 128), 255);
            int g = qBound(0, int((color.green() - 128) * factor + 128), 255);
            int b = qBound(0, int((color.blue() - 128) * factor + 128), 255);
            result.setPixel(x, y, qRgb(r, g, b));
        }
    }
    return result;
}
QImage ImageProcessor::sharpenImage(const QImage& image, int value)
{
    // 安全检查：确保图像有效且尺寸足够
    if (image.isNull() || image.width() < 3 || image.height() < 3) {
        return image; // 返回原图像
    }
    // 使用拉普拉斯算子进行锐化
    QImage result = image;
    // 创建锐化卷积核
    double kernel[3][3] = {
        {-1, -1, -1},
        {-1,  9, -1},
        {-1, -1, -1}
    };
    // 应用卷积，添加边界检查
    for (int y = 1; y < result.height() - 1; ++y) {
        for (int x = 1; x < result.width() - 1; ++x) {
            double r = 0, g = 0, b = 0;
            // 应用卷积核，为每个像素访问添加边界检查
            for (int ky = -1; ky <= 1; ++ky) {
                for (int kx = -1; kx <= 1; ++kx) {
                    int px = x + kx;
                    int py = y + ky;
                    // 双重安全检查
                    if (px >= 0 && px < image.width() && py >= 0 && py < image.height()) {
                        QColor color(image.pixel(px, py));
                        double k = kernel[ky+1][kx+1];
                        r += color.red() * k;
                        g += color.green() * k;
                        b += color.blue() * k;
                    }
                }
            }
            // 混合原始像素和锐化结果
            double blend = value / 100.0;
            QColor original(image.pixel(x, y));
            int finalR = qBound(0, int(original.red() * (1-blend) + r * blend), 255);
            int finalG = qBound(0, int(original.green() * (1-blend) + g * blend), 255);
            int finalB = qBound(0, int(original.blue() * (1-blend) + b * blend), 255);
            result.setPixel(x, y, qRgb(finalR, finalG, finalB));
        }
    }
    return result;
}
QImage ImageProcessor::denoiseImage(const QImage& image)
{
    // 安全检查：确保图像有效且尺寸足够
    if (image.isNull() || image.width() < 3 || image.height() < 3) {
        return image; // 返回原图像
    }
    // 使用中值滤波进行降噪
    QImage result = image;
    const int radius = 1;  // 3x3 窗口
    for (int y = radius; y < result.height() - radius; ++y) {
        for (int x = radius; x < result.width() - radius; ++x) {
            QVector<int> reds, greens, blues;
            // 收集邻域像素，添加边界检查
            for (int dy = -radius; dy <= radius; ++dy) {
                for (int dx = -radius; dx <= radius; ++dx) {
                    int px = x + dx;
                    int py = y + dy;
                    // 双重安全检查
                    if (px >= 0 && px < image.width() && py >= 0 && py < image.height()) {
                        QColor color(image.pixel(px, py));
                        reds.append(color.red());
                        greens.append(color.green());
                        blues.append(color.blue());
                    }
                }
            }
            // 防止空容器造成崩溃
            if (reds.isEmpty() || greens.isEmpty() || blues.isEmpty()) {
                continue; // 跳过该像素
            }
            // 排序并取中值
            std::sort(reds.begin(), reds.end());
            std::sort(greens.begin(), greens.end());
            std::sort(blues.begin(), blues.end());
            int medianIndex = reds.size() / 2;
            result.setPixel(x, y, qRgb(reds[medianIndex], 
                                     greens[medianIndex], 
                                     blues[medianIndex]));
        }
    }
    return result;
}
QImage ImageProcessor::autoRotateImage(const QImage& image)
{
    // TODO: 实现自动旋转校正
    // 这需要更复杂的图像分析算法
    return image;
}
QImage ImageProcessor::adjustColorMode(const QImage& image, int mode)
{
    QImage result = image;
    switch (mode) {
        case 1:  // 灰度
            for (int y = 0; y < result.height(); ++y) {
                for (int x = 0; x < result.width(); ++x) {
                    QColor color(result.pixel(x, y));
                    int gray = qGray(color.rgb());
                    result.setPixel(x, y, qRgb(gray, gray, gray));
                }
            }
            break;
        case 2:  // 黑白
            for (int y = 0; y < result.height(); ++y) {
                for (int x = 0; x < result.width(); ++x) {
                    QColor color(result.pixel(x, y));
                    int gray = qGray(color.rgb());
                    int bw = gray < 128 ? 0 : 255;
                    result.setPixel(x, y, qRgb(bw, bw, bw));
                }
            }
            break;
        case 3:  // 深褐色
            for (int y = 0; y < result.height(); ++y) {
                for (int x = 0; x < result.width(); ++x) {
                    QColor color(result.pixel(x, y));
                    int gray = qGray(color.rgb());
                    result.setPixel(x, y, qRgb(qMin(gray + 40, 255),
                                              gray,
                                              qMax(gray - 40, 0)));
                }
            }
            break;
        case 4:  // 反色
            for (int y = 0; y < result.height(); ++y) {
                for (int x = 0; x < result.width(); ++x) {
                    QColor color(result.pixel(x, y));
                    result.setPixel(x, y, qRgb(255 - color.red(),
                                              255 - color.green(),
                                              255 - color.blue()));
                }
            }
            break;
    }
    return result;
}
QList<int> ImageProcessor::findSplitPositions(const QImage& image, const QColor& bgColor)
{
    QList<int> positions;
    positions.append(0);  // 添加起始位置
    int height = image.height();
    int y = 0;
    while (y < height) {
        // 查找下一个分割点
        int nextPos = findBestSplitPosition(image, y, calculatePageHeight(image, LayoutMode::SingleColumn), bgColor);
        if (nextPos > y) {
            positions.append(nextPos);
            y = nextPos;
        } else {
            // 如果找不到合适的分割点，就强制分割
            y += calculatePageHeight(image, LayoutMode::SingleColumn);
            positions.append(qMin(y, height));
        }
    }
    return positions;
}
QImage ImageProcessor::createA4Page(const QImage& image, const QColor& bgColor)
{
    // Martin Fowler重构：Replace Magic Number - 使用动态DPI配置
    QSize a4Size = getCurrentA4Size();
    int a4Width = a4Size.width();
    int a4Height = a4Size.height();
    QImage result(a4Width, a4Height, QImage::Format_RGB32);
    result.fill(bgColor);
    // 计算缩放比例，保持纵横比
    double scale = qMin(
        static_cast<double>(a4Width) / image.width(),
        static_cast<double>(a4Height) / image.height()
    );
    int newWidth = static_cast<int>(image.width() * scale);
    int newHeight = static_cast<int>(image.height() * scale);
    // 计算居中位置
    int x = (a4Width - newWidth) / 2;
    int y = (a4Height - newHeight) / 2;
    // 绘制图像
    QPainter painter(&result);
    painter.setRenderHint(QPainter::SmoothPixmapTransform);
    painter.drawImage(QRect(x, y, newWidth, newHeight), image);
    return result;
}